package cn.com.dcsgo.service.impl;

import cn.com.dcsgo.common.PageInfo;
import cn.com.dcsgo.domain.dto.SysDictTypeQueryDTO;
import cn.com.dcsgo.domain.dto.SysDictTypeSaveDTO;
import cn.com.dcsgo.domain.dto.SysDictTypeUpdateDTO;
import cn.com.dcsgo.domain.po.SysDictType;
import cn.com.dcsgo.enums.ResultEnums;
import cn.com.dcsgo.exception.BusinessException;
import cn.com.dcsgo.mapper.SysDictTypeMapper;
import cn.com.dcsgo.service.SysBaseService;
import cn.com.dcsgo.service.SysDictDataService;
import cn.com.dcsgo.service.SysDictTypeService;
import cn.com.dcsgo.utils.ConverterUtils;
import com.github.pagehelper.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;

/**
 * SysDictTypeServiceImpl
 *
 * @author Dcsgo
 * @since 23/5/2025 上午 9:07
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysDictTypeServiceImpl implements SysBaseService<SysDictType>, SysDictTypeService {
    private final SysDictTypeMapper sysDictTypeMapper;
    private final SysDictDataService sysDictDataService;

    @Override
    public PageInfo<SysDictType, SysDictTypeQueryDTO> page(PageInfo<SysDictType, SysDictTypeQueryDTO> pageInfo) {
        // 开启分页
        Page<SysDictType> page = this.startPage(pageInfo.getPageNumber(), pageInfo.getPageSize());
        List<SysDictType> sysDictTypeList = sysDictTypeMapper.selectBySysDictTypeQueryDTO(pageInfo.getParams());

        // 封装分页查询结果
        pageInfo.setTotalCount(page.getTotal());
        pageInfo.setTotalPage(page.getPages());
        pageInfo.setList(sysDictTypeList);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public int save(SysDictTypeSaveDTO sysDictTypeSaveDTO) {
        // 判断新添加的字典类型是否已存在
        String dictType = sysDictTypeSaveDTO.getDictType();
        if (sysDictTypeMapper.hasDictType(dictType)) {
            // 存在直接异常退出
            throw new BusinessException(
                    ResultEnums.ERROR.getCode(),
                    "添加的字典类型: " + dictType + " 已存在"
            );
        }

        SysDictType sysDictType = new SysDictType();
        BeanUtils.copyProperties(sysDictTypeSaveDTO, sysDictType);

        // 填充其他属性
        sysDictType.setCreateTime(new Date());
        sysDictType.setCreateBy(getUsername());
        return sysDictTypeMapper.insertSelective(sysDictType);
    }

    @Override
    public int updateById(SysDictTypeUpdateDTO sysDictTypeUpdateDTO) {
        // 没有发送变化的参数不进行更改->置 null
        SysDictType updateData = sysDictTypeMapper.selectByPrimaryKey(sysDictTypeUpdateDTO.getDictId());
        Assert.notNull(updateData, "更新的字典类型不存在");
        ConverterUtils.syncFieldsWithNullOnEqual(sysDictTypeUpdateDTO, updateData, "dictId");

        // 修改字典类型时要判断新的字典类型是否已存在(如果有传参且为新数据的话)
        String newDictType = sysDictTypeUpdateDTO.getDictType();
        if (newDictType != null
                && updateData.getDictType() != null
                && sysDictTypeMapper.hasDictType(newDictType)) {
            throw new BusinessException(
                    ResultEnums.ERROR.getCode(),
                    "修改后的字典类型: " + newDictType + " 已存在"
            );
        }

        // 填充其他属性
        // 创建相关信息置 null 不进行更新
        updateData.setCreateBy(null);
        updateData.setCreateTime(null);
        updateData.setUpdateTime(new Date());
        updateData.setUpdateBy(getUsername());
        return sysDictTypeMapper.updateByPrimaryKeySelective(updateData);
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public int remove(Long dictId) {
        // 字典类型表通过 dict_type 与字典数据表关联
        SysDictType sysDictType = sysDictTypeMapper.selectByPrimaryKey(dictId);
        Assert.notNull(sysDictType, "不存在字典编号为: " + dictId + " 的字典类型");

        // 删除字典类型表中的数据
        int row = sysDictTypeMapper.deleteByPrimaryKey(dictId);

        // 删除字典数据表中的关联数据
        sysDictDataService.deleteByDictType(sysDictType.getDictType());

        return row;
    }

    @Override
    public SysDictType getDictTypeByDictId(Long dictId) {
        SysDictType dictType = sysDictTypeMapper.selectByPrimaryKey(dictId);
        log.debug("getDictTypeByDictId({}):{}", dictId, dictType);
        return dictType;
    }
}
